package cn.luckdou.commons.utils;

import java.security.Key;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;

/**
 * 3DES加密工具类
 * 
 * @author XianGuo
 *
 */
public class Des3Util {
	// 密钥
	private final static String secretKey = "scs@anan@bobo@xgx#partylive";
	// 向量
	private final static String iv = "01234567";
	// 加解密统一使用的编码方式
	private final static String encoding = "utf-8";
	
	
	public static void main(String[] args) throws Exception {
		String encode = encode("使用基于位置的鉴权，特定用户或网络结点的瞬间物理位置是位置签名唯一特征。这个签名由位置签名传感器(LSS)创建，由GPS的24小时卫星群通过微波信号发送。由独立设备使用这项技术，决定了LSS测量位置(在一个精确定义地理协同参考系统中的纬度，经度，和高度)，精读可以达到几米或更好。这个签名和导出位置是不可能伪造的。在网络空间的一个实体不能假装在任何地方，除了LSS实际定出的位置。当试图获得对一个主机服务器的访问，远程客户端要接受提供它当前位置签名的挑战。这个主机，自己也装备有LSS，同时处理客户端签名并获取卫星信号核实这个客户端的位置，是否在可接受的限值内(几米到几厘米，如果需要)。 对于双向鉴权，可以执行反过程。可以在几秒或更长时间执行重新授权。使用基于位置的鉴权，特定用户或网络结点的瞬间物理位置是位置签名唯一特征。这个签名由位置签名传感器(LSS)创建，由GPS的24小时卫星群通过微波信号发送。由独立设备使用这项技术，决定了LSS测量位置(在一个精确定义地理协同参考系统中的纬度，经度，和高度)，精读可以达到几米或更好。这个签名和导出位置是不可能伪造的。在网络空间的一个实体不能假装在任何地方，除了LSS实际定出的位置。当试图获得对一个主机服务器的访问，远程客户端要接受提供它当前位置签名的挑战。这个主机，自己也装备有LSS，同时处理客户端签名并获取卫星信号核实这个客户端的位置，是否在可接受的限值内(几米到几厘米，如果需要)。 对于双向鉴权，可以执行反过程。可以在几秒或更长时间执行重新授权。使用基于位置的鉴权，特定用户或网络结点的瞬间物理位置是位置签名唯一特征。这个签名由位置签名传感器(LSS)创建，由GPS的24小时卫星群通过微波信号发送。由独立设备使用这项技术，决定了LSS测量位置(在一个精确定义地理协同参考系统中的纬度，经度，和高度)，精读可以达到几米或更好。这个签名和导出位置是不可能伪造的。在网络空间的一个实体不能假装在任何地方，除了LSS实际定出的位置。当试图获得对一个主机服务器的访问，远程客户端要接受提供它当前位置签名的挑战。这个主机，自己也装备有LSS，同时处理客户端签名并获取卫星信号核实这个客户端的位置，是否在可接受的限值内(几米到几厘米，如果需要)。 对于双向鉴权，可以执行反过程。可以在几秒或更长时间执行重新授权。使用基于位置的鉴权，特定用户或网络结点的瞬间物理位置是位置签名唯一特征。这个签名由位置签名传感器(LSS)创建，由GPS的24小时卫星群通过微波信号发送。由独立设备使用这项技术，决定了LSS测量位置(在一个精确定义地理协同参考系统中的纬度，经度，和高度)，精读可以达到几米或更好。这个签名和导出位置是不可能伪造的。在网络空间的一个实体不能假装在任何地方，除了LSS实际定出的位置。当试图获得对一个主机服务器的访问，远程客户端要接受提供它当前位置签名的挑战。这个主机，自己也装备有LSS，同时处理客户端签名并获取卫星信号核实这个客户端的位置，是否在可接受的限值内(几米到几厘米，如果需要)。 对于双向鉴权，可以执行反过程。可以在几秒或更长时间执行重新授权。使用基于位置的鉴权，特定用户或网络结点的瞬间物理位置是位置签名唯一特征。这个签名由位置签名传感器(LSS)创建，由GPS的24小时卫星群通过微波信号发送。由独立设备使用这项技术，决定了LSS测量位置(在一个精确定义地理协同参考系统中的纬度，经度，和高度)，精读可以达到几米或更好。这个签名和导出位置是不可能伪造的。在网络空间的一个实体不能假装在任何地方，除了LSS实际定出的位置。当试图获得对一个主机服务器的访问，远程客户端要接受提供它当前位置签名的挑战。这个主机，自己也装备有LSS，同时处理客户端签名并获取卫星信号核实这个客户端的位置，是否在可接受的限值内(几米到几厘米，如果需要)。 对于双向鉴权，可以执行反过程。可以在几秒或更长时间执行重新授权。使用基于位置的鉴权，特定用户或网络结点的瞬间物理位置是位置签名唯一特征。这个签名由位置签名传感器(LSS)创建，由GPS的24小时卫星群通过微波信号发送。由独立设备使用这项技术，决定了LSS测量位置(在一个精确定义地理协同参考系统中的纬度，经度，和高度)，精读可以达到几米或更好。这个签名和导出位置是不可能伪造的。在网络空间的一个实体不能假装在任何地方，除了LSS实际定出的位置。当试图获得对一个主机服务器的访问，远程客户端要接受提供它当前位置签名的挑战。这个主机，自己也装备有LSS，同时处理客户端签名并获取卫星信号核实这个客户端的位置，是否在可接受的限值内(几米到几厘米，如果需要)。 对于双向鉴权，可以执行反过程。可以在几秒或更长时间执行重新授权。使用基于位置的鉴权，特定用户或网络结点的瞬间物理位置是位置签名唯一特征。这个签名由位置签名传感器(LSS)创建，由GPS的24小时卫星群通过微波信号发送。由独立设备使用这项技术，决定了LSS测量位置(在一个精确定义地理协同参考系统中的纬度，经度，和高度)，精读可以达到几米或更好。这个签名和导出位置是不可能伪造的。在网络空间的一个实体不能假装在任何地方，除了LSS实际定出的位置。当试图获得对一个主机服务器的访问，远程客户端要接受提供它当前位置签名的挑战。这个主机，自己也装备有LSS，同时处理客户端签名并获取卫星信号核实这个客户端的位置，是否在可接受的限值内(几米到几厘米，如果需要)。 对于双向鉴权，可以执行反过程。可以在几秒或更长时间执行重新授权。使用基于位置的鉴权，特定用户或网络结点的瞬间物理位置是位置签名唯一特征。这个签名由位置签名传感器(LSS)创建，由GPS的24小时卫星群通过微波信号发送。由独立设备使用这项技术，决定了LSS测量位置(在一个精确定义地理协同参考系统中的纬度，经度，和高度)，精读可以达到几米或更好。这个签名和导出位置是不可能伪造的。在网络空间的一个实体不能假装在任何地方，除了LSS实际定出的位置。当试图获得对一个主机服务器的访问，远程客户端要接受提供它当前位置签名的挑战。这个主机，自己也装备有LSS，同时处理客户端签名并获取卫星信号核实这个客户端的位置，是否在可接受的限值内(几米到几厘米，如果需要)。 对于双向鉴权，可以执行反过程。可以在几秒或更长时间执行重新授权。这项技术在鉴权用户时有很大收益，特别在厂内或远程位置，能增强无线信息安全。因为能很准确定位置，它很容易对在非常小的地理区域内的用户限制访问，并且拒绝连接或断开超出这个区域的用户。对于移动用户，基于物理位置的变化，它容易创建访问角色。根据用户的物理位置可以具有不同的角色/能力。当离开工厂时，使用膝上机的工程师权限会改变，限制在仅能察看访问。这项技术在增强控制系统的信息安全具有很大潜能。");
		System.out.println(encode);
		String decode = decode(encode);
		System.out.println(decode);
	}

	/**
	 * 3DES加密
	 * 
	 * @param plainText
	 *            普通文本
	 * @return
	 * @throws Exception
	 */
	public static String encode(String plainText) throws Exception {
		Key deskey = null;
		DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());
		SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
		deskey = keyfactory.generateSecret(spec);
		Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
		IvParameterSpec ips = new IvParameterSpec(iv.getBytes());
		cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
		byte[] encryptData = cipher.doFinal(plainText.getBytes(encoding));
		return Base64.encode(encryptData);
	}

	/**
	 * 3DES解密
	 * 
	 * @param encryptText
	 *            加密文本
	 * @return
	 * @throws Exception
	 */
	public static String decode(String encryptText) throws Exception {
		Key deskey = null;
		DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());
		SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
		deskey = keyfactory.generateSecret(spec);
		Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
		IvParameterSpec ips = new IvParameterSpec(iv.getBytes());
		cipher.init(Cipher.DECRYPT_MODE, deskey, ips);
		byte[] decryptData = cipher.doFinal(Base64.decode(encryptText));
		return new String(decryptData, encoding);
	}
}
